#ifndef UTILS__H
#define UTILS__H

#include <stdio.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <pwd.h>

#include <cjson/cJSON.h>
#include <yaml.h>

#include "struct.h"
#include "audit.h"

/* Hashmap */

unsigned long hash_string(const char *str)
{
    unsigned long hash = 5381;
    int c;
    while ((c = *str++))
    {
        hash = ((hash << 5) + hash) + c; // hash * 33 + c
    }
    return hash;
}

HashMap *hash_map_create(size_t capacity)
{
    HashMap *map = malloc(sizeof(HashMap));
    map->keys = malloc(sizeof(char *) * capacity);
    map->values = malloc(sizeof(int) * capacity); // 新增：初始化值数组
    map->occupied = calloc(capacity, sizeof(bool));
    map->capacity = capacity;
    map->size = 0;
    return map;
}

void hash_map_free(HashMap *map)
{
    for (size_t i = 0; i < map->capacity; i++)
    {
        if (map->occupied[i])
        {
            free(map->keys[i]);
        }
    }
    free(map->keys);
    free(map->values); // 新增：释放值数组
    free(map->occupied);
    free(map);
}

// 动态扩容和重新哈希的函数
bool hash_map_resize(HashMap *map, size_t new_capacity)
{
    char **new_keys = malloc(sizeof(char *) * new_capacity);
    int *new_values = malloc(sizeof(int) * new_capacity); // 新增：新值数组
    bool *new_occupied = calloc(new_capacity, sizeof(bool));
    if (!new_keys || !new_values || !new_occupied)
    {
        // 内存分配失败
        free(new_keys);
        free(new_values);
        free(new_occupied);
        return false;
    }

    for (size_t i = 0; i < map->capacity; i++)
    {
        if (map->occupied[i])
        {
            size_t index = hash_string(map->keys[i]) % new_capacity;
            while (new_occupied[index])
            { // 简单处理，实际可能需要优化
                index = (index + 1) % new_capacity;
            }
            new_keys[index] = map->keys[i];
            new_values[index] = map->values[i]; // 新增：复制值
            new_occupied[index] = true;
        }
    }

    free(map->keys);
    free(map->values); // 新增：释放旧值数组
    free(map->occupied);

    map->keys = new_keys;
    map->values = new_values; // 新增：更新值数组指针
    map->occupied = new_occupied;
    map->capacity = new_capacity;

    return true;
}

bool hash_map_insert(HashMap *map, const char *key)
{
    // 检查是否需要扩容
    if (map->size >= map->capacity * MAX_LOAD_FACTOR)
    {
        // 尝试加倍容量
        if (!hash_map_resize(map, map->capacity * 2))
        {
            return false; // 扩容失败
        }
    }

    size_t index = hash_string(key) % map->capacity;
    while (map->occupied[index])
    {
        if (strcmp(map->keys[index], key) == 0)
        {
            // 键已存在
            return true;
        }
        index = (index + 1) % map->capacity;
    }

    // 插入新键
    map->keys[index] = strdup(key);
    if (!map->keys[index])
        return false;               // 内存分配失败
    map->values[index] = map->size; // 新增：设置值为当前大小
    map->occupied[index] = true;
    map->size++;
    return true;
}

bool hash_map_search(const HashMap *map, const char *key, u32 *value)
{
    size_t index = hash_string(key) % map->capacity;
    while (map->occupied[index])
    {
        if (strcmp(map->keys[index], key) == 0)
        {
            *value = map->values[index]; // 新增：找到键时返回对应的值
            return true;
        }
        index = (index + 1) % map->capacity;
    }
    return false; // 键不存在
}
/**************************************************************************/

/* json file parse */

cJSON *parse_jsonfile(char *path)
{
    // 打开文件，获取文件内容
    FILE *file = fopen(path, "rb");
    if (NULL == file)
    {
        ebpflsm_error("无法打开该文件:%s", path);
        return NULL;
    }

    fseek(file, 0, SEEK_END);
    long length = ftell(file);
    fseek(file, 0, SEEK_SET);

    char *data = (char *)malloc(sizeof(char) * (length + 1));
    if (NULL == data)
    {
        ebpflsm_error("无法分配内存给文件:%s", path);
        fclose(file);
        return NULL;
    }

    fread(data, 1, length, file);
    data[length] = '\0';

    fclose(file);
    cJSON *ret_json_data = cJSON_Parse(data);
    free(data);
    return ret_json_data;
}

/**************************************************************************/

/* array string */

char **array_string_alloc(int arraysize, int strlength)
{
    int i;
    char **retArray = (char **)malloc(sizeof(char *) * arraysize);
    for (i = 0; i < arraysize; ++i)
    {
        retArray[i] = (char *)malloc(sizeof(char) * strlength);
    }
    return retArray;
}

void array_string_free(char **data, int len)
{
    int i;
    for (i = 0; i < len; ++i)
    {
        free(data[i]);
    }
    free(data);
}

/***************************************************************************/

// 文件处理相关函数

/**
 * @description: 提取路径的ino
 * @param {char} *path
 * @return {*}
 */
u64 path_to_ino(const char *path)
{
    struct stat sb;
    if (stat(path, &sb) == -1)
    {
        ebpflsm_error("Stat not right\n");
        return -1;
    }
    return sb.st_ino;
}

/***************************************************************************/

// yaml文件处理相关函数

/**
 * @description: 解析yaml文件,通过key解析得到value的值
 * @param {char} *path yaml文件的路径
 * @param {char} *key
 * @param {char} *value
 * @return {*}
 */
int parse_yaml(const char *path, const char *key, char *value)
{
    FILE *file = fopen(path, "r");
    if (!file)
    {
        ebpflsm_error("Failed to open yaml file: %s", path);
        return -1;
    }

    yaml_parser_t parser;
    yaml_document_t document;

    if (!yaml_parser_initialize(&parser))
    {
        ebpflsm_error("Failed to initialize yaml parser with file: %s!", path);
        fclose(file); // 关闭文件
        return -1;
    }

    yaml_parser_set_input_file(&parser, file);

    if (!yaml_parser_load(&parser, &document))
    {
        ebpflsm_error("Failed to load yaml document with file: %s!", path);
        yaml_parser_delete(&parser); // 销毁解析器
        fclose(file);                // 关闭文件
        return -1;
    }

    yaml_node_t *root = yaml_document_get_root_node(&document);
    if (!root)
    {
        ebpflsm_error("Empty YAML document: %s", path);
        yaml_document_delete(&document);
        yaml_parser_delete(&parser);
        fclose(file);
        return -1;
    }

    int found = 0;
    for (yaml_node_pair_t *pair = root->data.mapping.pairs.start;
         pair < root->data.mapping.pairs.top; pair++)
    {
        yaml_node_t *key_node = yaml_document_get_node(&document, pair->key);
        yaml_node_t *value_node = yaml_document_get_node(&document, pair->value);

        if (key_node->type == YAML_SCALAR_NODE && strcmp((char *)key_node->data.scalar.value, key) == 0)
        {
            if (value_node->type == YAML_SCALAR_NODE)
            {
                strcpy(value, (char *)value_node->data.scalar.value);
                found = 1;
                break;
            }
        }
    }

    yaml_document_delete(&document);
    yaml_parser_delete(&parser);
    fclose(file);

    if (!found)
    {
        ebpflsm_error("Key not found: %s", key);
        return -1;
    }

    return 0;
}

/**
 * @desciption: 将字符ipv4地址转换成为u32类型的地址
 * @param: char* ip_str
 * @return: u32 类型的ip地址
 */

u32 convert_ipstr(const char *ip_str)
{
    // u32 ip_num = ntohl(inet_addr(ip_str));//使用ntohl 转换为主机字节序列
    u32 ip_num = inet_addr(ip_str);
    return ip_num;
}
char *convert_ipbin(u32 ip_bin)
{
    struct in_addr addr = {};
    addr.s_addr = ip_bin;

    return inet_ntoa(addr);
}

/**
 * @desciption: 获取用户名在系统中的uid
 * @param: char* username 用户名
 * @return: u32 类型的ip地址 失败返回 __INT_MAX__
 */
u32 get_uid(const char *username)
{
    struct passwd *item = getpwnam(username);

    if (!item)
    {
        return __INT_MAX__;
    }

    return item->pw_uid;
}

#endif // !UTILS__H